package com.pai4j.common.util.community;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;

/**
 * MurMurHash算法，是非加密HASH算法，性能很高， 比传统的CRC32,MD5，SHA-1 等HASH算法要快很多，而且据说这个算法的碰撞率很低.
 */
public abstract class HashUtil {

    private static final int BARRIER_EIGHT = 8;

    private static final int BARRIER_ZERO = 0;

    private static final int ALLOCATE_SIZE = 8;

    private static final int SEED = 0x1234ABCD;

    private static final long COEFFICIENT = 0xc6a4a7935bd1e995L;

    private static final int DISPLACEMENT = 47;

    public static Long hash(String key) {

        ByteBuffer buf = ByteBuffer
                .wrap(key.getBytes(Charset.forName("UTF-8")));

        ByteOrder byteOrder = buf.order();
        buf.order(ByteOrder.LITTLE_ENDIAN);

        long h = SEED ^ (buf.remaining() * COEFFICIENT);

        long k;
        while (buf.remaining() >= BARRIER_EIGHT) {
            k = buf.getLong();

            k *= COEFFICIENT;
            k ^= k >>> DISPLACEMENT;
            k *= COEFFICIENT;

            h ^= k;
            h *= COEFFICIENT;
        }

        if (buf.remaining() > BARRIER_ZERO) {
            ByteBuffer finish = ByteBuffer.allocate(ALLOCATE_SIZE).order(
                    ByteOrder.LITTLE_ENDIAN);
            finish.put(buf).rewind();
            h ^= finish.getLong();
            h *= COEFFICIENT;
        }

        h ^= h >>> DISPLACEMENT;
        h *= COEFFICIENT;
        h ^= h >>> DISPLACEMENT;

        buf.order(byteOrder);
        return h;
    }
}

